home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / Sample Code / CALib & You… / Source / CASample / CAS_Content.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-07  |  39.2 KB  |  1,856 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        CAS_Content.c
  3.  
  4.     Contains:    CASample content element collection implementation
  5.  
  6.     Written by:    Rick Badertscher
  7.  
  8.     Copyright © 1993-1995 Apple Computer, All rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.                  9/1/95    RB        Created.
  13. */
  14.  
  15. #include "CAS_Globals.h"
  16. #include "CAS_Content.h"
  17.  
  18. #ifdef USE_CALIB
  19. #include "CAS_CAUtil.h"
  20. #endif
  21.  
  22. #include "CAS_Doc.h"
  23. #include "CAS_App.h"
  24.  
  25. #include "TraceLog.h"
  26.  
  27. //===========================================================================
  28. #pragma mark '    Content Element
  29. //===========================================================================
  30.  
  31.  
  32. //---------------------------------------------------------------------------
  33. ElemPtr    Elem_Read (            IOStreamPtr ioStream)
  34. {
  35.     long             length;
  36.     long            dataLength;
  37.     OSErr            theErr;
  38.     ElemPtr            theElem;
  39.     
  40.     theElem = (ElemPtr) NewPtr (sizeof (ElemRec));
  41.  
  42.     length = sizeof(ElemRec);
  43.     theErr = CAUtil_ReadWrapper (ioStream, (Ptr) theElem, &length);
  44.  
  45.     theElem->selRgn.cornerHandleRgn = NULL;
  46.     theElem->selRgn.edgeHandleRgn = NULL;
  47.     theElem->selRgn.selectRgn = NULL;
  48.     theElem->collection = NULL;
  49.     theElem->clipRgn = NULL;
  50.     theElem->visible = false;
  51.     theElem->clipInvalid = true;
  52.  
  53.     if (theElem->elemType == kPICTType)
  54.     {
  55.         length = sizeof(long);
  56.         theErr = CAUtil_ReadWrapper (ioStream, (Ptr) &dataLength, &length);
  57.         length = dataLength;
  58.         theElem->elemData = (Handle) NewHandle (dataLength);
  59.         theErr = CAUtil_ReadWrapper (ioStream, (Ptr) *(theElem->elemData), &length);
  60.     }
  61.             
  62.     return theElem;
  63.  
  64. }
  65.  
  66.  
  67. //---------------------------------------------------------------------------
  68. OSErr    Elem_Write (        ElemPtr theElem, IOStreamPtr ioStream)
  69. {
  70.     long             length;
  71.     OSErr            theErr;
  72.     long            dataLength;
  73.     
  74.     
  75.     if (theElem->elemType == kPICTType)
  76.     {
  77.         dataLength = GetHandleSize ((Handle)theElem->elemData);
  78.     }
  79.     else if (theElem->elemType == kFrameElemType)
  80.     {
  81.         dataLength = sizeof (CAFrameRef);
  82.     }
  83.     
  84.     length = sizeof (ElemRec);
  85.     theErr = CAUtil_WriteWrapper (ioStream, (Ptr) theElem, &length);
  86.  
  87.     if (theElem->elemType == kPICTType)
  88.     {
  89.         length = sizeof (long);
  90.         theErr = CAUtil_WriteWrapper (ioStream, (Ptr) &dataLength, &length);
  91.         length = dataLength;
  92.         HLock (theElem->elemData);
  93.         theErr = CAUtil_WriteWrapper (ioStream, (Ptr) *(theElem->elemData), &length);
  94.         HUnlock (theElem->elemData);
  95.  
  96.     }
  97.  
  98.     return theErr;
  99.  
  100. }
  101.  
  102. //---------------------------------------------------------------------------
  103. long            Elem_SpaceRequired(ElemPtr theElem)
  104. {
  105.     long    bytes = 0;
  106.     
  107.     bytes = sizeof (ElemRec);
  108.     bytes += sizeof (long);
  109.     
  110.     if (theElem->elemType == kPICTType)
  111.         bytes += GetHandleSize (theElem->elemData);
  112.  
  113.     return (bytes);
  114. }
  115.  
  116. //---------------------------------------------------------------------------
  117. // data is copied
  118. ElemPtr    Elem_New (    Handle            data,
  119.                     OSType            type,
  120.                     Rect            contentRect,
  121.                     Point            location)
  122. {
  123.  
  124.     ElemPtr                theElem;
  125.     
  126.     theElem = (ElemPtr) NewPtr (sizeof (ElemRec));
  127.     
  128.     if (type == kFrameElemType)
  129.         theElem->elemData = data;
  130.     else
  131.     {
  132.         // Clone the data handle
  133.         theElem->elemData = (Handle) NewHandle (GetHandleSize (data));
  134.         HLock (theElem->elemData);
  135.         HLock (data);
  136.         BlockMove (*data, *(theElem->elemData), GetHandleSize (data));
  137.         HUnlock (data);
  138.         HUnlock (theElem->elemData);
  139.     }
  140.     
  141.     theElem->elemType = type;
  142.     theElem->location = location;
  143.     theElem->contentRect = contentRect;
  144.     theElem->selected = false;
  145.     theElem->selRgn.cornerHandleRgn = NULL;
  146.     theElem->selRgn.edgeHandleRgn = NULL;
  147.     theElem->selRgn.selectRgn = NULL;
  148.     theElem->collection = NULL;
  149.     theElem->clipRgn = NULL;
  150.     theElem->visible = false;
  151.     theElem->clipInvalid = true;
  152.  
  153.     if (type == kFrameElemType)
  154.         theElem->resizable = true;
  155.     else
  156.         theElem->resizable = false;
  157.  
  158.     return (theElem);
  159.  
  160. }
  161.  
  162. //---------------------------------------------------------------------------
  163. void    Elem_UpdateCAFrame (ElemPtr theElem)
  164. {
  165.     RgnHandle        frameRgn;
  166.     Rect            contentRect;
  167.     
  168.     if (theElem->elemType != kFrameElemType) return;
  169.     
  170.     // Compute the frame rgn (in frame coordinates)
  171.     Elem_GetRect (theElem, &contentRect);
  172.     frameRgn = NewRgn();
  173.     RectRgn (frameRgn, &contentRect);
  174.     
  175.     // Update the CAFrame
  176.     CASetFrameRgn (ElemColl_GetDocPtr (theElem->collection)->partDocRef,
  177.                     (CAFrameRef) theElem->elemData, frameRgn);
  178.  
  179. }
  180.  
  181. //---------------------------------------------------------------------------
  182. void    Elem_UpdateCAVisFrame (ElemPtr theElem)
  183. {
  184. CAVisFrame        visFrame;
  185. CATransform        extTransform;
  186. Point            location;
  187. RgnHandle        frameRgn;
  188. Rect            contentRect;
  189.  
  190.     if (theElem->elemType != kFrameElemType) return;
  191.  
  192.     visFrame = CAGetVisFrame (ElemColl_GetDocPtr (theElem->collection)->partDocRef,
  193.                 (CAFrameRef) theElem->elemData);
  194.     
  195.     if (!visFrame) return;
  196.     
  197.     // Compute the frame region
  198.     Elem_GetRect (theElem, &contentRect);
  199.     frameRgn = NewRgn();
  200.     RectRgn (frameRgn, &contentRect);
  201.     
  202.     // Compute the external transform
  203.     Elem_GetLocation (theElem, &location);
  204.     
  205.     CAMoveTransformTo (&extTransform, location);
  206.     
  207.     // Update the facet
  208.     CAAdjustVisFrame (visFrame, frameRgn, &extTransform);
  209.  
  210. }
  211.  
  212.  
  213.  
  214. //---------------------------------------------------------------------------
  215. ElemPtr    Elem_Clone (    ElemPtr theElem)
  216. {
  217.  
  218.     ElemPtr                newElem;
  219.     
  220.     newElem = (ElemPtr) NewPtr (sizeof (ElemRec));
  221.     
  222.     newElem->elemData = theElem->elemData;
  223.     
  224.     if (theElem->elemType == kFrameElemType)
  225.         newElem->elemData = theElem->elemData;
  226.     else
  227.     {
  228.         // Clone the data handle
  229.         newElem->elemData = (Handle) NewHandle (GetHandleSize (theElem->elemData));
  230.         HLock (newElem->elemData);
  231.         HLock (theElem->elemData);
  232.         BlockMove (*(theElem->elemData), *(newElem->elemData), GetHandleSize (theElem->elemData));
  233.         HUnlock (newElem->elemData);
  234.         HUnlock (theElem->elemData);
  235.     }
  236.     
  237.     newElem->elemType = theElem->elemType;
  238.     newElem->location = theElem->location;
  239.     newElem->contentRect = theElem->contentRect;
  240.     newElem->selected = theElem->selected;
  241.     newElem->selRgn.cornerHandleRgn = NULL;
  242.     newElem->selRgn.edgeHandleRgn = NULL;
  243.     newElem->selRgn.selectRgn = NULL;
  244.     newElem->collection = NULL;
  245.     newElem->clipRgn = NULL;
  246.     newElem->visible = false;
  247.     newElem->clipInvalid = true;
  248.     newElem->resizable = theElem->resizable;
  249.  
  250.     return (newElem);
  251.  
  252. }
  253.  
  254.  
  255.  
  256. //---------------------------------------------------------------------------
  257. void    Elem_Remove (ElemPtr theElem)
  258. {
  259.  
  260.     Rect    docRect;
  261.     
  262.     if (theElem->elemType == kFrameElemType)
  263.     {
  264.         CARemoveFrameRef(ElemColl_GetDocPtr (theElem->collection)->partDocRef,
  265.             (CAFrameRef)(theElem->elemData));
  266.     }
  267.  
  268.     Elem_GetLocatedRect (theElem, &docRect);
  269.     InvalRect (&docRect);
  270.     
  271. }
  272.  
  273.  
  274. //---------------------------------------------------------------------------
  275. void    Elem_Free (ElemPtr theElem)
  276. {
  277.  
  278.     if (theElem->resizable)
  279.     {
  280.         if (theElem->selRgn.cornerHandleRgn)
  281.             DisposeRgn (theElem->selRgn.cornerHandleRgn);
  282.         
  283.         if (theElem->selRgn.edgeHandleRgn)
  284.             DisposeRgn (theElem->selRgn.edgeHandleRgn);
  285.     
  286.         if (theElem->selRgn.selectRgn)
  287.             DisposeRgn (theElem->selRgn.selectRgn);
  288.         
  289.         theElem->selRgn.cornerHandleRgn = NULL;
  290.         theElem->selRgn.edgeHandleRgn = NULL;
  291.         theElem->selRgn.selectRgn = NULL;
  292.     }
  293.     
  294.     switch (theElem->elemType)
  295.     {
  296.         case kPICTType:
  297.         
  298.             KillPicture ((PicHandle)theElem->elemData);
  299.             break;
  300.             
  301.         case kFrameElemType:
  302.             break;
  303.  
  304.         default: break;
  305.     }
  306.  
  307.     theElem->elemType = kNULLElemType;
  308.     DisposeRgn (theElem->clipRgn);
  309.     
  310.     DisposePtr ((Ptr)theElem);
  311.     
  312. }
  313.  
  314. //---------------------------------------------------------------------------
  315. void    Elem_SetRect(        ElemPtr theElem, Rect contentRect)
  316. {
  317.  
  318.     Rect    locatedRect;
  319.     
  320.     Elem_Invalidate (theElem);
  321.     
  322.     if (theElem->elemType == kPICTType)
  323.     {
  324.         theElem->contentRect = contentRect;
  325.  
  326.     }
  327.     else if (theElem->elemType == kFrameElemType)
  328.     {
  329.         Elem_Invalidate(theElem);
  330.         theElem->contentRect = contentRect;
  331.         Elem_CalcSelRgn (theElem);
  332.     }
  333.     
  334.     Elem_GetLocatedRect (theElem, &locatedRect);
  335.     
  336.     ElemColl_ClipElements(theElem->collection, &locatedRect);
  337.     Elem_Invalidate(theElem);
  338.  
  339.  
  340. }
  341.  
  342. //---------------------------------------------------------------------------
  343. void    Elem_GetRect(        ElemPtr theElem, Rect* contentRect)
  344. {
  345.     
  346.     *contentRect = theElem->contentRect;
  347.     
  348. }
  349.  
  350. //---------------------------------------------------------------------------
  351. void    Elem_GetLocatedRect(ElemPtr theElem, Rect* contentRect)
  352. {
  353.     
  354.     *contentRect = theElem->contentRect;
  355.     OffsetRect (contentRect, theElem->location.h, theElem->location.v);
  356.     
  357. }
  358.  
  359.  
  360. //---------------------------------------------------------------------------
  361. void    Elem_GetDisplayRect(ElemPtr theElem, Rect* displayRect)
  362. {
  363.  
  364.     switch (theElem->elemType)
  365.     {
  366.     
  367.         case kPICTType:
  368.  
  369.             *displayRect = theElem->contentRect;
  370.             OffsetRect (displayRect, theElem->location.h, theElem->location.v);
  371.     
  372.             break;
  373.             
  374.         case kFrameElemType:
  375.         
  376.             if (theElem->selected)
  377.             {
  378.                 *displayRect = (**(theElem->selRgn.selectRgn)).rgnBBox;
  379.             }
  380.             else
  381.             {
  382.                 *displayRect = theElem->contentRect;
  383.                 OffsetRect (displayRect, theElem->location.h, theElem->location.v);
  384.             }
  385.             
  386.             break;
  387.             
  388.         default: break;
  389.     }
  390. }
  391.  
  392.  
  393.  
  394. //---------------------------------------------------------------------------
  395. void Elem_GetLocation(        ElemPtr theElem, Point* location)
  396. {
  397.     *location = theElem->location;
  398. }
  399.  
  400. //---------------------------------------------------------------------------
  401. void Elem_SetLocation(        ElemPtr theElem, Point location)
  402. {
  403.     Rect    affectedArea, initialRect;
  404.     
  405.     // The initial rect
  406.     Elem_GetLocatedRect (theElem, &initialRect);
  407.     
  408.     Elem_Invalidate (theElem);
  409.     
  410.     if (theElem->elemType == kPICTType)
  411.     {
  412.         theElem->location = location;
  413.     }
  414.     else if (theElem->elemType == kFrameElemType)
  415.     {
  416.         theElem->location = location;
  417.         Elem_CalcSelRgn (theElem);
  418.         Elem_UpdateCAVisFrame (theElem);
  419.     }
  420.     
  421.     // The final rect
  422.     Elem_GetLocatedRect (theElem, &affectedArea);
  423.     UnionRect (&initialRect, &affectedArea, &affectedArea);
  424.     ElemColl_ClipElements(theElem->collection, &affectedArea);
  425.     
  426.     Elem_Invalidate(theElem);
  427.     
  428. }
  429.  
  430.  
  431. //---------------------------------------------------------------------------
  432. void    Elem_SetSelected(    ElemPtr    theElem, Boolean selected)
  433. {
  434. CAVisFrame    visFrame;
  435.  
  436.     if (theElem->elemType == kFrameElemType)
  437.     {
  438.         visFrame = CAGetVisFrame (ElemColl_GetDocPtr (theElem->collection)->partDocRef,
  439.             (CAFrameRef)(theElem->elemData));
  440.         CASetSelected (visFrame, selected);
  441.     }
  442.  
  443.     // Invalidate before we recalculate incase it's deselecting
  444.     Elem_InvalSelRgn (theElem);
  445.     
  446.     theElem->selected = selected;
  447.     
  448.     // Recalc the sel rgns
  449.     Elem_CalcSelRgn (theElem);
  450.     
  451.     // Invalidate
  452.     Elem_Invalidate (theElem);
  453.     
  454.     
  455. }
  456.  
  457. //---------------------------------------------------------------------------
  458. Boolean    Elem_GetSelected(    ElemPtr    theElem)
  459. {
  460.     return (theElem->selected);
  461. }
  462.  
  463. //---------------------------------------------------------------------------
  464. void    Elem_SetVisible(    ElemPtr    theElem, Boolean visible)
  465. {
  466.  
  467.     CATransform        extTransform;
  468.     CAVisFrame        visFrame;
  469.     
  470.     if (visible == false) Elem_Invalidate (theElem);
  471.     
  472.     theElem->visible = visible;
  473.     
  474.     switch (theElem->elemType)
  475.     {
  476.     
  477.         case kPICTType:
  478.             break;
  479.             
  480.         case kFrameElemType:
  481.         
  482.             if (visible)
  483.             {
  484.             
  485.                 // Create a facet for the new frame
  486.             
  487.                 CAMoveTransformTo (&extTransform, theElem->location);
  488.                 CAMakeVisFrame(ElemColl_GetDocPtr (theElem->collection)->partDocRef,
  489.                                 (CAFrameRef) theElem->elemData, NULL, &extTransform, NULL);
  490.                 
  491.                 // Set the facet as selected
  492.                 if (theElem->selected)
  493.                 {
  494.                     visFrame = CAGetVisFrame (ElemColl_GetDocPtr (theElem->collection)->partDocRef,
  495.                                             (CAFrameRef)(theElem->elemData));
  496.                     CASetSelected (visFrame, true);
  497.                 }
  498.  
  499.             }
  500.             
  501.             Elem_CalcSelRgn (theElem);
  502.             break;
  503.         
  504.     }
  505.     
  506.     Elem_Invalidate (theElem);
  507. }
  508.  
  509.  
  510. //---------------------------------------------------------------------------
  511. OSType Elem_GetType(        ElemPtr    theElem)
  512. {
  513.     return (theElem->elemType);
  514. }
  515.  
  516. //---------------------------------------------------------------------------
  517. void Elem_Draw(ElemPtr theElem, Boolean drawSel)
  518. {
  519.  
  520.     Rect        docRect;
  521.     CAVisFrame    visFrame;
  522.     
  523.     if (!theElem->visible) return;
  524.     
  525.     if (theElem->clipInvalid)
  526.         Elem_CalcClipRgn (theElem);
  527.         
  528.     switch (theElem->elemType)
  529.     {
  530.     
  531.         case kPICTType:
  532.             
  533.             Elem_GetLocatedRect (theElem, &docRect);
  534.             DrawPicture( (PicHandle) theElem->elemData, &docRect );
  535.  
  536.             // invert the item (for now) to indicate selection.
  537.             if (drawSel && theElem->selected)
  538.                 InvertRect( &docRect );
  539.  
  540.             
  541.             break;
  542.             
  543.         case kFrameElemType:
  544.         {
  545.         
  546.             TRACE (3, "Elem_Draw - FRAME");
  547.  
  548.             // Get the visFrame
  549.             visFrame = CAGetVisFrame( ElemColl_GetDocPtr (theElem->collection)->partDocRef, 
  550.                                         (CAFrameRef)theElem->elemData);
  551.  
  552.             CADrawFrame ( visFrame, NULL);
  553.             
  554.             if (drawSel && theElem->selected)
  555.                 Elem_DrawSelRgn (theElem);
  556.             break;
  557.         }
  558.         
  559.     }
  560.  
  561. }
  562.  
  563. //---------------------------------------------------------------------------
  564. void Elem_Invalidate(ElemPtr theElem)
  565. {
  566. GrafPtr        savePort;
  567. Rect        docRect;
  568.  
  569.     TRACE (3, "Elem_Invalidate");
  570.  
  571.     if (!theElem->visible) return;
  572.     
  573.     GetPort( &savePort );
  574.     SetPort( Doc_GetWindow(ElemColl_GetDocPtr(theElem->collection)));
  575.  
  576.     Elem_GetLocatedRect (theElem, &docRect);
  577.  
  578.     switch (theElem->elemType)
  579.     {
  580.     
  581.         case kPICTType:
  582.             InvalRect (&docRect);
  583.             break;
  584.             
  585.         case kFrameElemType:
  586.             InvalRect (&docRect);
  587.             if (theElem->selected)
  588.                 Elem_InvalSelRgn (theElem);
  589.                 
  590.             break;
  591.     
  592.     }
  593.  
  594.     SetPort( savePort );
  595.     
  596. }
  597.  
  598. void Elem_CalcClipRgn (ElemPtr theElem)
  599. {
  600.     RgnHandle    displayRgn, coveredRgn;
  601.     RgnHandle    tempRgn = NULL;
  602.     Rect        displayRect;
  603.     CAVisFrame    visFrame;
  604.     Boolean        anyCovered = false;
  605.     
  606.     if (!theElem->visible) return;
  607.  
  608.     // Reuse clipRgn
  609.     if (theElem->clipRgn == NULL)
  610.         displayRgn = NewRgn();
  611.     else
  612.         displayRgn = theElem->clipRgn;
  613.  
  614.     // Calc the content element display region
  615.     Elem_GetLocatedRect (theElem, &displayRect);
  616.     RectRgn (displayRgn, &displayRect);
  617.     
  618.     // Get the area of the content element which is covered
  619.     coveredRgn = NewRgn();
  620.     ElemColl_GetRgnOverElem (theElem->collection, theElem, coveredRgn);
  621.  
  622.     // Subtract the covered region from the display region
  623.     DiffRgn (displayRgn, coveredRgn, displayRgn);
  624.     
  625.     if (!EmptyRgn (coveredRgn))
  626.         anyCovered = true;
  627.         
  628.     DisposeRgn (coveredRgn);
  629.     theElem->clipRgn = displayRgn;
  630.     
  631.     switch (theElem->elemType)
  632.     {
  633.         
  634.         case kPICTType:
  635.         
  636.             TRACE (3, "Elem_CalcClipRgn for PICT");
  637.             break;
  638.             
  639.         case kFrameElemType:
  640.         
  641.             TRACE (3, "Elem_CalcClipRgn for FRAME");
  642.  
  643.             // Set the clipping region for the embedded frame
  644.             visFrame = CAGetVisFrame( ElemColl_GetDocPtr (theElem->collection)->partDocRef, 
  645.                                         (CAFrameRef)theElem->elemData);
  646.  
  647.             if (anyCovered)
  648.             {
  649.                 TRACE (3, "Elem_CalcClipRgn for FRAME, some is covered");
  650.  
  651.                 tempRgn = NewRgn();
  652.                 CopyRgn (theElem->clipRgn, tempRgn);
  653.                 OffsetRgn (tempRgn, - ((**tempRgn).rgnBBox.left), - ((**tempRgn).rgnBBox.top));
  654.             }
  655.             else
  656.             {
  657.                 // Clip to the frames used region
  658.                 tempRgn = CAGetUsedRgn ( ElemColl_GetDocPtr (theElem->collection)->partDocRef, 
  659.                                         (CAFrameRef)theElem->elemData);
  660.                                         
  661.                 TRACE (3, "Elem_CalcClipRgn for FRAME, NONE is covered");
  662.             }
  663.             
  664.             if (visFrame)
  665.                 CAAdjustVisFrame ( visFrame, tempRgn, NULL);
  666.             
  667.             break;
  668.     }
  669.     
  670.     theElem->clipInvalid = false;
  671.     
  672. }
  673.  
  674. void Elem_InvalClipRgn (ElemPtr theElem)
  675. {
  676.     theElem->clipInvalid = true;
  677. }
  678.  
  679. //---------------------------------------------------------------------------
  680. void        Elem_DrawSelRgn (ElemPtr theElem)
  681. {
  682.     WindowPtr        theWindow;
  683.     CAHighlight        highlight = kCANoHighlight;
  684.     RgnHandle        saveClip;
  685.     Rect            theRect;
  686.     short            baseH, baseV;
  687.  
  688.     if (!theElem->visible) return;
  689.     if (!theElem->selected) return;
  690.  
  691.     theWindow = Doc_GetWindow(ElemColl_GetDocPtr(theElem->collection));
  692.     
  693.     // save the ClipRgn
  694.     
  695.     saveClip = NewRgn();
  696.     GetClip( saveClip );
  697.  
  698.     // Set clip to whole window
  699.     
  700.     theRect = ElemColl_GetDocPtr(theElem->collection)->contentRect;
  701.  
  702.     baseH = GetControlValue( ElemColl_GetDocPtr(theElem->collection)->hScrollBar );
  703.     baseV = GetControlValue( ElemColl_GetDocPtr(theElem->collection)->vScrollBar );
  704.     
  705.     OffsetRect( &theRect, baseH, baseV);
  706.  
  707.     ClipRect (&theRect);
  708.  
  709.     if (Elem_GetSelected (theElem))
  710.     {
  711.         highlight = kCAFullHighlight;
  712.     }
  713.     
  714.     PenMode (patXor);
  715.  
  716.     // If the root frame is not the active frame then draw dimmed selection handles
  717.     
  718.     if ((gFocusDocument != ElemColl_GetDocPtr(theElem->collection)->partDocRef) ||
  719.         gInBackground)
  720.     {
  721.         highlight = kCADimHighlight;
  722.     }
  723.         
  724.     if (highlight == kCAFullHighlight)
  725.     {
  726.     
  727.         FillRgn(theElem->selRgn.selectRgn, &(qd.gray));
  728.         FillRgn(theElem->selRgn.cornerHandleRgn, &(qd.black));
  729.         FillRgn(theElem->selRgn.edgeHandleRgn, &(qd.black));
  730.         
  731.     }
  732.     else if (highlight == kCADimHighlight)
  733.     {
  734.         
  735.         // draw frame border
  736.         
  737.         FillRgn(theElem->selRgn.selectRgn, &(qd.gray));
  738.     
  739.     }
  740.     
  741.     PenNormal();
  742.     SetClip(saveClip);
  743.  
  744. }
  745.  
  746. //---------------------------------------------------------------------------
  747. void Elem_InvalSelRgn (ElemPtr theElem)
  748. {
  749.  
  750.     if (theElem->selRgn.cornerHandleRgn)
  751.     {
  752.         InvalRgn (theElem->selRgn.cornerHandleRgn);
  753.         InvalRgn (theElem->selRgn.edgeHandleRgn);
  754.         InvalRgn (theElem->selRgn.selectRgn);
  755.     }
  756.             
  757. }
  758.  
  759. //---------------------------------------------------------------------------
  760.  
  761. void Elem_CalcSelRgn (ElemPtr theElem)
  762. {
  763.     Rect                resizeHandle;
  764.     Point                handleVertice;
  765.     RgnHandle            frameShapeRgn;
  766.     RgnHandle            border;
  767.     RgnHandle            edgeHdlRgn;
  768.     RgnHandle            cornerHdlRgn;
  769.     Rect                borderRect;
  770.     RgnHandle            coveredRgn;
  771.     Rect                rect;
  772.     
  773.     if (theElem->selRgn.cornerHandleRgn)
  774.         DisposeRgn (theElem->selRgn.cornerHandleRgn);
  775.         
  776.     if (theElem->selRgn.edgeHandleRgn)
  777.         DisposeRgn (theElem->selRgn.edgeHandleRgn);
  778.     
  779.     if (theElem->selRgn.selectRgn)
  780.         DisposeRgn (theElem->selRgn.selectRgn);
  781.         
  782.     theElem->selRgn.cornerHandleRgn = NULL;
  783.     theElem->selRgn.edgeHandleRgn = NULL;
  784.     theElem->selRgn.selectRgn = NULL;
  785.     
  786.     if (theElem->selected == false) return;
  787.     
  788.     // -- selection border region --
  789.     
  790.     border = NewRgn();
  791.  
  792.     Elem_GetLocatedRect (theElem, &rect);
  793.     frameShapeRgn = NewRgn();
  794.     RectRgn (frameShapeRgn, &rect);
  795.     
  796.     //frameShapeRgn = CAFrame_GetCAFrameRgn (frame);
  797.     CopyRgn (frameShapeRgn, border);
  798.  
  799.     InsetRgn(border, -1, -1);
  800.     DiffRgn(border, frameShapeRgn, border);
  801.  
  802.     borderRect = (**border).rgnBBox;
  803.  
  804.     // -- corner region --
  805.  
  806.     cornerHdlRgn = NewRgn();
  807.     OpenRgn ();
  808.     
  809.     // Handles
  810.     
  811.     // Left Top
  812.     handleVertice.h = borderRect.left - 2;
  813.     handleVertice.v = borderRect.top - 2;
  814.     SetRect (&resizeHandle, handleVertice.h, handleVertice.v,
  815.                 handleVertice.h + kBorderWidth, handleVertice.v + kBorderWidth);
  816.     FrameRect (&resizeHandle);
  817.                 
  818.     // Left Bottom
  819.     handleVertice.h = borderRect.left - 2;
  820.     handleVertice.v = borderRect.bottom - 3;
  821.     SetRect (&resizeHandle, handleVertice.h, handleVertice.v,
  822.                 handleVertice.h + kBorderWidth, handleVertice.v + kBorderWidth);
  823.     FrameRect (&resizeHandle);
  824.  
  825.     // Right top
  826.     handleVertice.h = borderRect.right - 3;
  827.     handleVertice.v = borderRect.top - 2;
  828.     SetRect (&resizeHandle, handleVertice.h, handleVertice.v,
  829.                 handleVertice.h + kBorderWidth, handleVertice.v + kBorderWidth);
  830.     FrameRect (&resizeHandle);
  831.  
  832.     // Right Bottom
  833.     handleVertice.h = borderRect.right - 3;
  834.     handleVertice.v = borderRect.bottom - 3;
  835.     SetRect (&resizeHandle, handleVertice.h, handleVertice.v,
  836.                 handleVertice.h + kBorderWidth, handleVertice.v + kBorderWidth);
  837.     FrameRect (&resizeHandle);
  838.  
  839.     CloseRgn(cornerHdlRgn);
  840.  
  841.     // -- edge handle region --
  842.  
  843.     edgeHdlRgn = NewRgn();
  844.     OpenRgn ();
  845.     
  846.     // Handles
  847.     
  848.     // middle Top
  849.     handleVertice.h = borderRect.left + ((borderRect.right - borderRect.left) / 2) - 2;
  850.     handleVertice.v = borderRect.top - 2;
  851.     SetRect (&resizeHandle, handleVertice.h, handleVertice.v,
  852.                 handleVertice.h + kBorderWidth, handleVertice.v + kBorderWidth);
  853.     FrameRect (&resizeHandle);
  854.                 
  855.     // middle Bottom
  856.     handleVertice.h = borderRect.left + ((borderRect.right - borderRect.left) / 2) - 2;
  857.     handleVertice.v = borderRect.bottom - 3;
  858.     SetRect (&resizeHandle, handleVertice.h, handleVertice.v,
  859.                 handleVertice.h + kBorderWidth, handleVertice.v + kBorderWidth);
  860.     FrameRect (&resizeHandle);
  861.  
  862.     // Left middle
  863.     handleVertice.h = borderRect.left - 2;
  864.     handleVertice.v = borderRect.top + ((borderRect.bottom - borderRect.top) / 2) - 2;
  865.     SetRect (&resizeHandle, handleVertice.h, handleVertice.v,
  866.                 handleVertice.h + kBorderWidth, handleVertice.v + kBorderWidth);
  867.     FrameRect (&resizeHandle);
  868.  
  869.     // Right middle
  870.     handleVertice.h = borderRect.right - 3;
  871.     handleVertice.v = borderRect.top + ((borderRect.bottom - borderRect.top) / 2) - 2;
  872.     SetRect (&resizeHandle, handleVertice.h, handleVertice.v,
  873.                 handleVertice.h + kBorderWidth, handleVertice.v + kBorderWidth);
  874.     FrameRect (&resizeHandle);
  875.  
  876.     CloseRgn (edgeHdlRgn);
  877.     
  878.     // coveredRgn represents the display area used
  879.     // by frames above "frame" in the z-order.
  880.     
  881.     coveredRgn = NewRgn();
  882.     ElemColl_GetRgnOverElem ( theElem->collection, theElem, coveredRgn);
  883.     
  884.     // Let frames about "frame" hide the selection regions
  885.     
  886.     DiffRgn (cornerHdlRgn, coveredRgn, cornerHdlRgn);
  887.     DiffRgn (edgeHdlRgn, coveredRgn, edgeHdlRgn);
  888.     DiffRgn (border, coveredRgn, border);
  889.     
  890.     theElem->selRgn.cornerHandleRgn = cornerHdlRgn;
  891.     theElem->selRgn.edgeHandleRgn = edgeHdlRgn;
  892.     theElem->selRgn.selectRgn = border;
  893.     
  894.     Elem_Invalidate (theElem);
  895.     
  896. }
  897.  
  898. //---------------------------------------------------------------------------
  899.  
  900. Boolean Elem_HandleMouseDown (    ElemPtr            theElem,
  901.                                 DocPtr            theDoc,
  902.                                 EventRecord*    event)
  903. {
  904.  
  905.     Boolean        retVal = false;
  906.     WindowPtr    theWindow;
  907.     
  908.     theWindow = Doc_GetWindow (theDoc);
  909.  
  910.     if (gShiftPressed)
  911.     {
  912.     
  913.         ElemColl_MoveElemToFront(theDoc->contentColl, theElem);
  914.         Elem_SetSelected (theElem, !Elem_GetSelected (theElem));
  915.  
  916.         Win_Update (theWindow);
  917.         Drag_DragItem( theWindow, event);
  918.  
  919.     }
  920.     else
  921.     {
  922.     
  923.         if (theWindow == App_GetFrontDocWindow())
  924.         {
  925.  
  926.             if (!Elem_GetSelected (theElem))
  927.             {
  928.                 ElemColl_MoveElemToFront(theDoc->contentColl, theElem);
  929.                 Doc_SelectAllElements (theDoc, false);
  930.                 Elem_SetSelected (theElem, true);
  931.             }
  932.  
  933.             Win_Update (theWindow);
  934.             Drag_DragItem( theWindow, event);
  935.             
  936.         }
  937.                     
  938.     }
  939.     
  940.     return retVal;
  941.     
  942. }
  943.  
  944. //---------------------------------------------------------------------------
  945.  
  946. void Elem_HandleMouseInCornerResize (    ElemPtr            theElem,
  947.                                         DocPtr            theDoc,
  948.                                         Point*            mouse,
  949.                                         EventRecord*    event)
  950. {
  951. #pragma unused (event)
  952.  
  953.     ResizeHandle    growCorner = kNone;
  954.     WindowPtr        window;
  955.     Point            center;
  956.     Rect            sr;
  957.     Rect            growBox;
  958.     Rect            oldBox;
  959.     Rect            qdRect;
  960.     Point            delta, theLoc;
  961.     Point            lastLoc = {0,0};
  962.     Point            transOffset = {0,0};
  963.     GrafPtr            curPort;
  964.  
  965.     theLoc = *mouse;
  966.     
  967.     window = Doc_GetWindow (theDoc);
  968.     
  969.     GetPort(&curPort);
  970.     SetPort(window);
  971.  
  972.     Elem_GetLocatedRect(theElem, &sr);
  973.  
  974.     SetPt(¢er, ((sr).right + (sr).left) / 2, ((sr).bottom + (sr).top) / 2);        // center of FrameShape
  975.     
  976.     if        ((mouse->v <= center.v) && (mouse->h <= center.h)) growCorner = kTL;
  977.     else if ((mouse->v <  center.v) && (mouse->h >  center.h)) growCorner = kTR;
  978.     else if ((mouse->v >  center.v) && (mouse->h <  center.h)) growCorner = kBL;
  979.     else if ((mouse->v >  center.v) && (mouse->h >  center.h)) growCorner = kBR;
  980.         
  981.     growBox = (sr);
  982.     SetRect (&oldBox, 0,0,0,0);
  983.     
  984.     PenMode(patXor);
  985.     PenPat(&(qd.gray));
  986.     
  987.     while (WaitMouseUp())
  988.     {
  989.         GetMouse(&theLoc);
  990.         
  991.         if ((theLoc.h != lastLoc.h) || (theLoc.v != lastLoc.v))
  992.         {
  993.             switch (growCorner) 
  994.             {
  995.                 case kTL:
  996.                     growBox.top = theLoc.v;
  997.                     growBox.left = theLoc.h;
  998.                     break;
  999.  
  1000.                 case kTR:
  1001.                     growBox.top = theLoc.v;
  1002.                     growBox.right = theLoc.h;
  1003.                     break;
  1004.  
  1005.                 case kBL:
  1006.                     growBox.left = theLoc.h;
  1007.                     growBox.bottom = theLoc.v;
  1008.                     break;
  1009.  
  1010.                 case kBR:
  1011.                     growBox.bottom = theLoc.v;
  1012.                     growBox.right = theLoc.h;
  1013.                     break;
  1014.                 
  1015.                 default:
  1016.                     break;
  1017.             }
  1018.             
  1019.             FrameRect(&oldBox);
  1020.             FrameRect(&growBox);
  1021.         }
  1022.         
  1023.         lastLoc = theLoc;
  1024.         oldBox = growBox;
  1025.     }
  1026.     
  1027.     FrameRect(&oldBox);
  1028.     
  1029.     PenPat(&(qd.gray));
  1030.     PenMode(patCopy);
  1031.     
  1032.     SetOrigin(0,0);
  1033.  
  1034.     delta.h = theLoc.h - mouse->h; //where.h;
  1035.     delta.v = theLoc.v - mouse->v; //where.v;
  1036.  
  1037.     qdRect = theElem->contentRect;
  1038.  
  1039.     switch (growCorner)
  1040.     {
  1041.         case kTL:
  1042.         
  1043.             if (delta.v > qdRect.bottom)
  1044.                 delta.v = qdRect.bottom - 1;
  1045.             if (delta.h > qdRect.right)
  1046.                 delta.h = qdRect.right - 1;
  1047.                 
  1048.             qdRect.bottom -= delta.v; qdRect.right -= delta.h;
  1049.             transOffset.v += delta.v; transOffset.h += delta.h;
  1050.             break;
  1051.  
  1052.         case kTR:
  1053.             
  1054.             if (delta.v > qdRect.bottom)
  1055.                 delta.v = qdRect.bottom - 1;
  1056.             if (qdRect.right + delta.h < 0)
  1057.                 delta.h = - qdRect.right + 1;
  1058.  
  1059.             qdRect.bottom -= delta.v; qdRect.right += delta.h;
  1060.             transOffset.v += delta.v;
  1061.             break;
  1062.  
  1063.         case kBL:
  1064.         
  1065.             if (qdRect.bottom + delta.v < 0)
  1066.                 delta.v = - qdRect.bottom + 1;
  1067.             if (delta.h > qdRect.right)
  1068.                 delta.h = qdRect.right - 1;
  1069.  
  1070.         
  1071.             qdRect.bottom += delta.v; qdRect.right -= delta.h;
  1072.             transOffset.h += delta.h;
  1073.             break;
  1074.  
  1075.         case kBR:
  1076.         
  1077.             if (qdRect.bottom + delta.v < 0)
  1078.                 delta.v = - qdRect.bottom + 1;
  1079.             if (qdRect.right + delta.h < 0)
  1080.                 delta.h = - qdRect.right + 1;
  1081.  
  1082.             qdRect.bottom += delta.v;
  1083.             qdRect.right += delta.h;
  1084.             break;
  1085.  
  1086.         default:
  1087.             break;
  1088.     }
  1089.  
  1090.     
  1091.     Elem_Invalidate (theElem);
  1092.     
  1093.     // Resize & relocate the Element
  1094.     
  1095.     Elem_SetRect (theElem, qdRect);
  1096.     
  1097.     if ((transOffset.h != 0) || (transOffset.v != 0))
  1098.     {
  1099.         Point    position;
  1100.         
  1101.         Elem_GetLocation (theElem, &position);
  1102.         
  1103.         position.v += transOffset.v;
  1104.         position.h += transOffset.h;
  1105.         
  1106.         Elem_SetLocation (theElem, position);
  1107.     
  1108.     }
  1109.  
  1110.     ElemColl_MoveElemToFront (theDoc->contentColl, theElem);
  1111.  
  1112.     // Update the CAFrame & CAVisFrame
  1113.     Elem_UpdateCAFrame (theElem);
  1114.     Elem_UpdateCAVisFrame (theElem);
  1115.     
  1116.     SetPort (curPort);
  1117.     
  1118.     return;
  1119.  
  1120. }
  1121.  
  1122. //---------------------------------------------------------------------------
  1123.  
  1124. void Elem_HandleMouseInEdgeResize (        ElemPtr            theElem,
  1125.                                         DocPtr            theDoc,
  1126.                                         Point*            mouse,
  1127.                                         EventRecord*    event)
  1128. {
  1129. #pragma unused (event)
  1130.  
  1131.     ResizeHandle    growEdge = kNone;
  1132.     WindowPtr        window;
  1133.     Point            center;
  1134.     Rect            sr;
  1135.     Rect            growBox;
  1136.     Rect            oldBox;
  1137.     Rect            qdRect;
  1138.     Point            delta, theLoc;
  1139.     Point            lastLoc = {0,0};
  1140.     Point            transOffset = {0,0};
  1141.     GrafPtr            curPort;
  1142.  
  1143.     theLoc = *mouse;
  1144.     
  1145.     window = Doc_GetWindow (theDoc);
  1146.     
  1147.     GetPort(&curPort);
  1148.     SetPort(window);
  1149.  
  1150.     Elem_GetLocatedRect(theElem, &sr);
  1151.  
  1152.     SetPt(¢er, ((sr).right + (sr).left) / 2, ((sr).bottom + (sr).top) / 2);        // center of FrameShape
  1153.     
  1154.     if        (mouse->v <= (sr.top + (0.1 * sr.top))) growEdge = kTE;
  1155.     else if (mouse->h <= (sr.left + (0.1 * sr.left))) growEdge = kLE;
  1156.     else if (mouse->v >= (sr.bottom - (0.1 * sr.bottom))) growEdge = kBE;
  1157.     else if (mouse->h >= (sr.right -  (0.1 * sr.right))) growEdge = kRE;
  1158.         
  1159.     //this->UTIL_SetGrafPortOrigin(ev, facet);
  1160.     growBox = (sr);
  1161.     SetRect (&oldBox, 0,0,0,0);
  1162.     
  1163.     PenMode(patXor);
  1164.     PenPat(&(qd.gray));
  1165.     
  1166.     while (WaitMouseUp())
  1167.     {
  1168.         GetMouse(&theLoc);
  1169.         
  1170.         if ((theLoc.h != lastLoc.h) || (theLoc.v != lastLoc.v))
  1171.         {
  1172.             switch (growEdge) 
  1173.             {
  1174.                 case kLE:
  1175.                     growBox.left = theLoc.h;
  1176.                     break;
  1177.  
  1178.                 case kRE:
  1179.                     growBox.right = theLoc.h;
  1180.                     break;
  1181.  
  1182.                 case kBE:
  1183.                     growBox.bottom = theLoc.v;
  1184.                     break;
  1185.  
  1186.                 case kTE:
  1187.                     growBox.top = theLoc.v;
  1188.                     break;
  1189.                 
  1190.                 default:
  1191.                     break;
  1192.             }
  1193.             
  1194.             FrameRect(&oldBox);
  1195.             FrameRect(&growBox);
  1196.         }
  1197.         
  1198.         lastLoc = theLoc;
  1199.         oldBox = growBox;
  1200.     }
  1201.     
  1202.     FrameRect(&oldBox);
  1203.     
  1204.     PenPat(&(qd.gray));
  1205.     PenMode(patCopy);
  1206.     
  1207.     SetOrigin(0,0);
  1208.  
  1209.     delta.h = theLoc.h - mouse->h; //where.h;
  1210.     delta.v = theLoc.v - mouse->v; //where.v;
  1211.  
  1212.     qdRect = theElem->contentRect;
  1213.  
  1214.     switch (growEdge)
  1215.     {
  1216.         case kLE:
  1217.  
  1218.             if (delta.h > qdRect.right)
  1219.                 delta.h = qdRect.right - 1;
  1220.             qdRect.right -= delta.h;
  1221.             transOffset.h += delta.h;
  1222.             
  1223.             break;
  1224.             
  1225.         case kRE:
  1226.             
  1227.             if (qdRect.right + delta.h < 0)
  1228.                 delta.h = - qdRect.right + 1;
  1229.             qdRect.right += delta.h;
  1230.             
  1231.             break;
  1232.  
  1233.         case kTE:
  1234.         
  1235.             if (delta.v > qdRect.bottom)
  1236.                 delta.v = qdRect.bottom - 1;
  1237.             qdRect.bottom -= delta.v;
  1238.             transOffset.v += delta.v;
  1239.             break;
  1240.  
  1241.         case kBE:
  1242.         
  1243.             if (qdRect.bottom + delta.v < 0)
  1244.                 delta.v = - qdRect.bottom + 1;
  1245.             qdRect.bottom += delta.v;
  1246.             break;
  1247.  
  1248.         default:
  1249.             break;
  1250.     }
  1251.  
  1252.     
  1253.     Elem_Invalidate (theElem);
  1254.     
  1255.     // Resize & relocate the Element
  1256.     
  1257.     Elem_SetRect (theElem, qdRect);
  1258.     
  1259.     if ((transOffset.h != 0) || (transOffset.v != 0))
  1260.     {
  1261.         Point    position;
  1262.         
  1263.         Elem_GetLocation (theElem, &position);
  1264.         
  1265.         position.v += transOffset.v;
  1266.         position.h += transOffset.h;
  1267.         
  1268.         Elem_SetLocation (theElem, position);
  1269.     
  1270.     }
  1271.  
  1272.     // Update the CAFrame & CAVisFrame
  1273.     Elem_UpdateCAFrame (theElem);
  1274.     Elem_UpdateCAVisFrame (theElem);
  1275.     
  1276.     ElemColl_MoveElemToFront (theDoc->contentColl, theElem);
  1277.         
  1278.     SetPort (curPort);
  1279.     
  1280.     return;
  1281.  
  1282. }
  1283.  
  1284.  
  1285. //===========================================================================
  1286. #pragma mark '    Content Element Collection
  1287. //===========================================================================
  1288.  
  1289. //---------------------------------------------------------------------------
  1290. void    ElemColl_Init(            ElemCollPtr theColl, DocPtr theDoc)
  1291. {
  1292.  
  1293.     theColl->docPtr = theDoc;
  1294.     ElemList_Init (&(theColl->elemList));
  1295. }
  1296.  
  1297. //---------------------------------------------------------------------------
  1298. // Free the collection, but don't delete the elements
  1299. void    ElemColl_Free(            ElemCollPtr theColl)
  1300. {
  1301.     ElemNodePtr            node;
  1302.     ElemNodePtr            nextNode;
  1303.     
  1304.     node = ElemList_GetHeadNode (&(theColl->elemList));
  1305.     
  1306.     while (node)
  1307.     {
  1308.         // Free the node
  1309.         nextNode = node->nextNode;
  1310.         DisposePtr ((Ptr) node);
  1311.         node = nextNode;
  1312.     }
  1313.  
  1314.     (&(theColl->elemList))->headNode = NULL;
  1315.     (&(theColl->elemList))->tailNode = NULL;
  1316. }
  1317.  
  1318. //---------------------------------------------------------------------------
  1319. // Free the collection, delete the elements
  1320. void    ElemColl_FreeAll(            ElemCollPtr theColl)
  1321. {
  1322.     ElemNodePtr            node;
  1323.     ElemNodePtr            nextNode;
  1324.     ElemPtr                elem;
  1325.     
  1326.     node = ElemList_GetHeadNode (&(theColl->elemList));
  1327.     
  1328.     while (node)
  1329.     {
  1330.         // Free the element
  1331.         elem = node->elemPtr;
  1332.         Elem_Free (elem);
  1333.         
  1334.         // Free the node
  1335.         nextNode = node->nextNode;
  1336.         DisposePtr ((Ptr) node);
  1337.         node = nextNode;
  1338.     }
  1339.  
  1340.     (&(theColl->elemList))->headNode = NULL;
  1341.     (&(theColl->elemList))->tailNode = NULL;
  1342. }
  1343.  
  1344.  
  1345. //---------------------------------------------------------------------------
  1346. void    ElemColl_ClipElements(ElemCollPtr theColl, Rect* clipArea)
  1347. {
  1348.     ElemPtr            elem;
  1349.     ElemNodePtr        node;
  1350.     Rect            rect;
  1351.     Rect            intersectionRect;
  1352.     
  1353.     node = ElemList_GetHeadNode (&(theColl->elemList));
  1354.     
  1355.     while (node)
  1356.     {
  1357.         elem = node->elemPtr;
  1358.         Elem_GetLocatedRect (elem, &rect);
  1359.         
  1360.         if (clipArea)
  1361.         {
  1362.         
  1363.             // If this element overlaps clipArea then recalc clip region
  1364.             SectRect (clipArea, &rect, &intersectionRect);
  1365.             
  1366.             if (!EmptyRect (&intersectionRect))
  1367.                 Elem_InvalClipRgn (elem);
  1368.             
  1369.         }
  1370.         else
  1371.             Elem_InvalClipRgn (elem);
  1372.  
  1373.         
  1374.         node = node->nextNode;
  1375.         
  1376.     }
  1377.     
  1378. }
  1379.  
  1380.  
  1381. //---------------------------------------------------------------------------
  1382. void    ElemColl_AddElem(        ElemCollPtr theColl, ElemPtr theElem)
  1383. {
  1384.  
  1385.     ElemNodePtr            node;
  1386.     
  1387.     theElem->collection = theColl;
  1388.  
  1389.     node = (ElemNodePtr) NewPtr (sizeof (ElemNode));
  1390.     node->nextNode = NULL;
  1391.     node->elemPtr = theElem;
  1392.     
  1393.     ElemList_AddNode (&(theColl->elemList), node);
  1394.  
  1395. }
  1396.  
  1397. //---------------------------------------------------------------------------
  1398. void    ElemColl_AddElemTemp(        ElemCollPtr theColl, ElemPtr theElem)
  1399. {
  1400.  
  1401.     ElemNodePtr            node;
  1402.     
  1403.     node = (ElemNodePtr) NewPtr (sizeof (ElemNode));
  1404.     node->nextNode = NULL;
  1405.     node->elemPtr = theElem;
  1406.     
  1407.     ElemList_AddNode (&(theColl->elemList), node);
  1408.  
  1409. }
  1410.  
  1411.  
  1412.  
  1413. //---------------------------------------------------------------------------
  1414. void        ElemColl_RemoveElem(ElemCollPtr theColl, ElemPtr theElem)
  1415. {
  1416.  
  1417.     ElemNodePtr        node;
  1418.     Rect            rect;
  1419.     
  1420.     node = ElemList_RemoveNode (&(theColl->elemList), theElem);
  1421.  
  1422.     Elem_GetLocatedRect (theElem, &rect);
  1423.     Elem_Invalidate(theElem);
  1424.     Elem_Remove (theElem);
  1425.     Elem_Free (theElem);
  1426.     DisposePtr ((Ptr) node);
  1427.     
  1428.     ElemColl_ClipElements(theColl, &rect);
  1429.  
  1430. }
  1431.  
  1432. //---------------------------------------------------------------------------
  1433. short        ElemColl_GetCount(ElemCollPtr theColl)
  1434. {
  1435.     return (ElemList_GetCount (&(theColl->elemList)));
  1436. }
  1437.  
  1438. //---------------------------------------------------------------------------
  1439. short        ElemColl_GetCountOfType(ElemCollPtr theColl, OSType elemType)
  1440. {
  1441.     short        count = 1;
  1442.     short        total = 0;
  1443.     ElemNodePtr    node;
  1444.     
  1445.     if (elemType == kNULLElemType)
  1446.     {
  1447.         return (ElemList_GetCount (&(theColl->elemList)));
  1448.     }
  1449.     else
  1450.     {
  1451.     
  1452.         node = ElemList_GetHeadNode (&(theColl->elemList));
  1453.  
  1454.         while (node)
  1455.         {
  1456.             if (node->elemPtr->elemType == elemType)
  1457.             {
  1458.                 ++total;
  1459.             }
  1460.             node = node->nextNode;
  1461.         }
  1462.     }
  1463.     
  1464.     return (total);
  1465. }
  1466.  
  1467.  
  1468. //---------------------------------------------------------------------------
  1469. short ElemColl_FindElem(ElemCollPtr theColl, Point mouse, ElemPtr* theElem)
  1470.  
  1471. {
  1472.     ElemPtr            elem;
  1473.     ElemNodePtr        node;
  1474.     ElemNodePtr        matchedNode = NULL;
  1475.     short            partCode = inElement;
  1476.     Rect            docRect;
  1477.     
  1478.     node = ElemList_GetHeadNode (&(theColl->elemList));
  1479.     
  1480.     while (node)
  1481.     {
  1482.         
  1483.         elem = node->elemPtr;
  1484.         Elem_GetLocatedRect (elem, &docRect);
  1485.         
  1486.         if (PtInRect (mouse, &docRect))
  1487.         {
  1488.             partCode = inElement;
  1489.             matchedNode = node;
  1490.         }
  1491.         else if (elem->selected)
  1492.         {
  1493.         
  1494.             if (PtInRgn (mouse, elem->selRgn.cornerHandleRgn))
  1495.             {
  1496.                 partCode = inCornerResize;
  1497.                 matchedNode = node;
  1498.                 break;
  1499.             }
  1500.             
  1501.             else if (PtInRgn (mouse, elem->selRgn.edgeHandleRgn))
  1502.             {
  1503.                 partCode = inEdgeResize;
  1504.                 matchedNode = node;
  1505.                 break;
  1506.             }
  1507.             
  1508.         }
  1509.         
  1510.         node = node->nextNode;
  1511.         
  1512.     }
  1513.     
  1514.     if (matchedNode)
  1515.         *theElem = matchedNode->elemPtr;
  1516.     else
  1517.         *theElem = NULL;
  1518.     
  1519.     return (partCode);
  1520.     
  1521. }
  1522.  
  1523.  
  1524. //---------------------------------------------------------------------------
  1525. ElemPtr    ElemColl_GetNthElem(    ElemCollPtr theColl, short index)
  1526. {
  1527.     return (ElemList_GetNthElem (&(theColl->elemList), index));
  1528. }
  1529.  
  1530. //---------------------------------------------------------------------------
  1531. ElemPtr    ElemColl_GetNthElemOfType(    ElemCollPtr theColl, short index, OSType type)
  1532. {
  1533.  
  1534.     ElemPtr            elem;
  1535.     ElemNodePtr        node;
  1536.     short            count;
  1537.     short            typeCount = 0;
  1538.     Boolean            matched = false;
  1539.     short            listCount;
  1540.     
  1541.     listCount = ElemList_GetCount (&(theColl->elemList));
  1542.     
  1543.     if ( (index > listCount) || (index < 1)) DebugStr ("\p ElemColl_GetNthElem - invalid index");
  1544.     
  1545.     node = ElemList_GetHeadNode (&(theColl->elemList));
  1546.     
  1547.     for (count = 1; count <= listCount; ++count)
  1548.     {
  1549.         if (!node) DebugStr ("\pElemColl - list ptr error");
  1550.         
  1551.         if (node->elemPtr->elemType == type) ++typeCount;
  1552.         
  1553.         if (typeCount == index)
  1554.         {
  1555.             matched = true;
  1556.             break;
  1557.         }
  1558.         node = node->nextNode;
  1559.     
  1560.     }
  1561.     
  1562.     elem = node->elemPtr;
  1563.     
  1564.     return (elem);
  1565.  
  1566. }
  1567.  
  1568. //---------------------------------------------------------------------------
  1569. DocPtr    ElemColl_GetDocPtr(    ElemCollPtr theColl)
  1570. {
  1571.     return (theColl->docPtr);
  1572. }
  1573.  
  1574.  
  1575. //---------------------------------------------------------------------------
  1576. void        ElemColl_MoveElemToFront(ElemCollPtr theColl, ElemPtr theElem)
  1577. {
  1578.     ElemNodePtr    node;
  1579.     Rect        rect;
  1580.     
  1581.     // Move the elemNode to the head of the ElemList
  1582.     node = ElemList_RemoveNode (&(theColl->elemList), theElem);
  1583.     ElemList_AddNode (&(theColl->elemList), node);
  1584.     Elem_GetLocatedRect (theElem, &rect);
  1585.     ElemColl_ClipElements(theColl, &rect);
  1586.     Elem_Invalidate (theElem);
  1587.  
  1588. }
  1589.  
  1590.  
  1591. //---------------------------------------------------------------------------
  1592. // Computes the region made up of all elements which are above
  1593. // theElem in the z-order.
  1594.  
  1595. void ElemColl_GetRgnOverElem (ElemCollPtr theColl, ElemPtr theElem, RgnHandle rgn)
  1596. {
  1597.  
  1598.     ElemNodePtr        node;
  1599.     ElemNodePtr        tmpNode;
  1600.     Rect            rect;
  1601.     RgnHandle        usedRgn;
  1602.     Point            location;
  1603.     
  1604.     node = ElemList_GetNode (&(theColl->elemList), theElem);
  1605.     tmpNode = ElemList_GetHeadNode (&(theColl->elemList));
  1606.     
  1607.     // Accumulate the used region of all elements above the target element
  1608.     // All nodes after the target node (up to the tail node) are above the target node
  1609.     // in the z-order
  1610.     
  1611.     tmpNode = node;
  1612.     
  1613.     while (tmpNode->nextNode != NULL)
  1614.     {
  1615.         tmpNode = tmpNode->nextNode;
  1616.         
  1617.         if (Elem_GetType (tmpNode->elemPtr) == kFrameElemType)
  1618.         {
  1619.             usedRgn = CAGetUsedRgn (ElemColl_GetDocPtr (tmpNode->elemPtr->collection)->partDocRef,
  1620.                         (CAFrameRef)(tmpNode->elemPtr->elemData));
  1621.                         
  1622.             // Transform usedRgn to document coordinates
  1623.             Elem_GetLocation (tmpNode->elemPtr, &location);
  1624.             OffsetRgn (usedRgn, location.h, location.v);
  1625.             
  1626.         }
  1627.         else
  1628.         {
  1629.             usedRgn = NewRgn();
  1630.             Elem_GetLocatedRect (tmpNode->elemPtr, &rect);
  1631.             RectRgn (usedRgn, &rect);
  1632.         }
  1633.         
  1634.         UnionRgn (rgn, usedRgn, rgn);
  1635.         DisposeRgn (usedRgn);
  1636.  
  1637.         // also the selection regions
  1638.  
  1639.         if (Elem_GetSelected (tmpNode->elemPtr))
  1640.         {
  1641.             CAHighlight    highlight = kCAFullHighlight;
  1642.             
  1643.             if ((gFocusDocument != ElemColl_GetDocPtr(theElem->collection)->partDocRef) ||
  1644.                     gInBackground)
  1645.             {
  1646.                 highlight = kCADimHighlight;
  1647.             }
  1648.             
  1649.             if (highlight == kCAFullHighlight)
  1650.             {
  1651.                 UnionRgn (rgn, theElem->selRgn.selectRgn, rgn);
  1652.                 UnionRgn (rgn, theElem->selRgn.cornerHandleRgn, rgn);
  1653.                 UnionRgn (rgn, theElem->selRgn.edgeHandleRgn, rgn);
  1654.             }
  1655.             else if (highlight == kCADimHighlight)
  1656.             {
  1657.                 UnionRgn (rgn, theElem->selRgn.selectRgn, rgn);
  1658.             }
  1659.             
  1660.  
  1661.         }
  1662.         
  1663.     }
  1664.  
  1665. }
  1666.  
  1667. //---------------------------------------------------------------------------
  1668. ElemListPtr ElemColl_GetCurrentSelection (ElemCollPtr theColl)
  1669. {
  1670.  
  1671.     ElemListPtr            selectionList;
  1672.     short                count;
  1673.     short                i;
  1674.     ElemNodePtr            node;
  1675.     ElemPtr                elem;
  1676.     
  1677.     selectionList = (ElemListPtr) NewPtr (sizeof (ElemList));
  1678.     ElemList_Init (selectionList);
  1679.     
  1680.     count = ElemColl_GetCount (theColl);
  1681.     
  1682.     for (i=1; i <= count; ++i)
  1683.     {
  1684.         elem = ElemColl_GetNthElem (theColl, i);
  1685.  
  1686.         if (Elem_GetSelected (elem))
  1687.         {
  1688.             node = (ElemNodePtr) NewPtr (sizeof (ElemNode));
  1689.             node->nextNode = NULL;
  1690.             node->elemPtr = elem;
  1691.  
  1692.             ElemList_AddNode (selectionList, node); 
  1693.         }
  1694.     }
  1695.  
  1696.     return (selectionList);
  1697.     
  1698.  
  1699. }
  1700.  
  1701.  
  1702. //===========================================================================
  1703. #pragma mark '    Content Element List
  1704. //===========================================================================
  1705.  
  1706. //---------------------------------------------------------------------------
  1707. void ElemList_Init (ElemListPtr theList)
  1708. {
  1709.     theList->headNode = NULL;
  1710.     theList->tailNode = NULL;
  1711.     theList->count = 0;
  1712. }
  1713.  
  1714. //---------------------------------------------------------------------------
  1715. void ElemList_Free (ElemListPtr    theList)
  1716. {
  1717.     
  1718.     ElemNodePtr        node;
  1719.     ElemNodePtr        tmpNode;
  1720.     
  1721.     node = theList->headNode;
  1722.     
  1723.     while (node)
  1724.     {
  1725.     
  1726.         tmpNode = node->nextNode;
  1727.         DisposePtr ((Ptr) tmpNode);
  1728.         node = tmpNode;
  1729.     
  1730.     }
  1731.  
  1732.     DisposePtr ((Ptr)theList);
  1733.     
  1734. }
  1735.  
  1736.  
  1737. //---------------------------------------------------------------------------
  1738. void ElemList_AddNode (ElemListPtr theList, ElemNodePtr theNode)
  1739. {
  1740.  
  1741.     if (theList->headNode)
  1742.     {
  1743.         theList->tailNode->nextNode = theNode;
  1744.         theList->tailNode = theNode;
  1745.     }
  1746.     else
  1747.     {
  1748.         theList->headNode = theNode;
  1749.         theList->tailNode = theNode;
  1750.     }
  1751.     
  1752.     ++theList->count;
  1753.  
  1754. }
  1755.  
  1756. //---------------------------------------------------------------------------
  1757. ElemNodePtr ElemList_RemoveNode (ElemListPtr theList, ElemPtr theElem)
  1758. {
  1759.  
  1760.     ElemNodePtr        node;
  1761.     ElemNodePtr        prevNode;
  1762.     
  1763.     node = theList->headNode;
  1764.     prevNode = NULL;
  1765.     
  1766.     while (node)
  1767.     {
  1768.     
  1769.         if (node->elemPtr == theElem)
  1770.         {
  1771.             break;
  1772.         }
  1773.         
  1774.         prevNode = node;
  1775.         node = node->nextNode;
  1776.     
  1777.     }
  1778.     
  1779.     if (node)
  1780.     {
  1781.         if (prevNode) prevNode->nextNode = node->nextNode;
  1782.         if (node == theList->headNode) theList->headNode = node->nextNode;
  1783.         if (node == theList->tailNode) theList->tailNode = prevNode;
  1784.         --theList->count;
  1785.  
  1786.     }
  1787.  
  1788.     node->nextNode = NULL;
  1789.     return (node);
  1790.     
  1791. }
  1792.  
  1793. //---------------------------------------------------------------------------
  1794. ElemNodePtr ElemList_GetNode (ElemListPtr theList, ElemPtr theElem)
  1795. {
  1796.  
  1797.     ElemNodePtr        tmpNode;
  1798.     ElemNodePtr        matchedNode;
  1799.     
  1800.     tmpNode = ElemList_GetHeadNode (theList);
  1801.     
  1802.     while (tmpNode)
  1803.     {
  1804.         if (tmpNode->elemPtr == theElem)
  1805.         {
  1806.             matchedNode = tmpNode;
  1807.             break;
  1808.         }
  1809.         tmpNode = tmpNode->nextNode;
  1810.     }
  1811.     
  1812.     return matchedNode;
  1813.     
  1814. }
  1815.  
  1816.  
  1817. //---------------------------------------------------------------------------
  1818. ElemNodePtr    ElemList_GetHeadNode (ElemListPtr theList)
  1819. {
  1820.     return (theList->headNode);
  1821. }
  1822.  
  1823. //---------------------------------------------------------------------------
  1824. short            ElemList_GetCount(ElemListPtr theList)
  1825. {
  1826.     return (theList->count);
  1827. }
  1828.  
  1829. //---------------------------------------------------------------------------
  1830. ElemPtr            ElemList_GetNthElem(ElemListPtr theList, short index)
  1831. {
  1832.  
  1833.     ElemPtr            elem;
  1834.     ElemNodePtr        node;
  1835.     short            count;
  1836.     
  1837.     if ((index > theList->count) || (index < 1)) DebugStr ("\p ElemList_GetNthElem - invalid index");
  1838.     
  1839.     node = ElemList_GetHeadNode (theList);
  1840.     
  1841.     for (count = 1; count < index; ++count)
  1842.     {
  1843.         if (!node) DebugStr ("\pElemList - list ptr error");
  1844.         
  1845.         node = node->nextNode;
  1846.     
  1847.     }
  1848.     
  1849.     elem = node->elemPtr;
  1850.     
  1851.     return (elem);
  1852.  
  1853. }
  1854.  
  1855.  
  1856.